using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Text.RegularExpressions;
using System.Threading;
using System.Windows.Data;
using System.Windows.Threading;
using Ricciolo.PaperBoy.Feeds;
using Ricciolo.PaperBoy.Feeds.Rss;

namespace Ricciolo.PaperBoy.UI
{
    public class FeedItemListCollectionView : CollectionView
    {
        private readonly IFeedItem item;
        private bool firstRefresh = true;
        private readonly ObservableCollectionEx<IFeedItem> list;

        public FeedItemListCollectionView(IFeedItem item)
            : base(new ObservableCollectionEx<IFeedItem>())
        {
            this.item = item;
            this.list = (ObservableCollectionEx<IFeedItem>)this.SourceCollection;
        }

        public override bool IsEmpty
        {
            get
            {
                return item.CommentsCount == 0;
            }
        }

        protected override void RefreshOverride()
        {
            if (item.CommentRss == null) return;

            if (firstRefresh)
            {
                OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
                firstRefresh = false;
                return;
            }

            // Add fake record
            using (list.StartDeferRefresh(false))
            {
                list.Clear();
                list.Add(new WaitFeedItem());
            }
            InvalidateData();

            // Load async
            ThreadPool.QueueUserWorkItem(LoadComments);
        }

        private void LoadComments(object state)
        {
            RssFeed feed = RssFeed.Read(item.CommentRss.ToString());

            // Add items to the list
            this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new WaitCallback(OnLoadCommentsCompleted), feed);
        }

        private void OnLoadCommentsCompleted(object state)
        {
            RssFeed feed = (RssFeed) state;
            using (this.list.StartDeferRefresh(false))
            {
                this.list.Clear();

                if (feed.Channels.Count > 0)
                    foreach (IFeedItem feedItem in feed.Channels[0].Items)
                    {
                        list.Add(feedItem);
                    }
            }
            InvalidateData();
        }

        private void InvalidateData()
        {
            base.OnPropertyChanged(new PropertyChangedEventArgs("Count"));
            base.OnPropertyChanged(new PropertyChangedEventArgs("Item[]"));
            base.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
        }
    }
}